package com.galen.manual.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.galen.manual.dto.BannerCreateDTO;
import com.galen.manual.dto.BannerQueryDTO;
import com.galen.manual.entity.Banner;
import com.galen.manual.mapper.BannerMapper;
import com.galen.manual.service.BannerService;
import com.galen.manual.service.MinioService;
import com.galen.manual.vo.BannerListVO;
import com.galen.manual.vo.BannerVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class BannerServiceImpl implements BannerService {

    private final BannerMapper bannerMapper;
    private final MinioService minioService;

    @Override
    public Page<BannerListVO> getBannerPage(BannerQueryDTO queryDTO) {
        log.info("获取Banner列表，标题: {}, 状态: {}, 页码: {}, 每页大小: {}",
                queryDTO.getTitle(), queryDTO.getStatus(), queryDTO.getPageNum(), queryDTO.getPageSize());

        QueryWrapper<Banner> queryWrapper = new QueryWrapper<>();

        // 标题搜索
        if (queryDTO.getTitle() != null && !queryDTO.getTitle().trim().isEmpty()) {
            queryWrapper.like("title", queryDTO.getTitle());
        }

        // 状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }

        // 链接类型筛选
        if (queryDTO.getLinkType() != null) {
            queryWrapper.eq("link_type", queryDTO.getLinkType());
        }

        // 按排序值和创建时间排序
        queryWrapper.orderByAsc("sort_order")
                  .orderByDesc("create_time");

        // 分页查询
        Page<Banner> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        Page<Banner> bannerPage = bannerMapper.selectPage(page, queryWrapper);

        // 转换为VO
        Page<BannerListVO> voPage = new Page<>();
        BeanUtils.copyProperties(bannerPage, voPage);
        voPage.setRecords(bannerPage.getRecords().stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList()));

        return voPage;
    }

    @Override
    public List<BannerListVO> getActiveBanners() {
        log.info("获取启用的Banner列表");

        QueryWrapper<Banner> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1); // 启用状态

        // 检查时间范围
        LocalDateTime now = LocalDateTime.now();
        queryWrapper.and(wrapper -> wrapper
            .isNull("start_time")
            .or()
            .le("start_time", now)
        );
        queryWrapper.and(wrapper -> wrapper
            .isNull("end_time")
            .or()
            .ge("end_time", now)
        );

        queryWrapper.orderByAsc("sort_order")
                  .orderByDesc("create_time");

        List<Banner> banners = bannerMapper.selectList(queryWrapper);
        return banners.stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList());
    }

    @Override
    public BannerVO getBannerDetail(Long id) {
        log.info("获取Banner详情，ID: {}", id);

        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new RuntimeException("Banner不存在");
        }

        return convertToDetailVO(banner);
    }

    @Override
    public void createBanner(BannerCreateDTO createDTO) {
        log.info("创建Banner: {}", createDTO.getTitle());

        Banner banner = new Banner();
        BeanUtils.copyProperties(createDTO, banner);

        bannerMapper.insert(banner);
        log.info("Banner创建成功，ID: {}", banner.getId());
    }

    @Override
    public void updateBanner(Long id, BannerCreateDTO updateDTO) {
        log.info("更新Banner: {} - {}", id, updateDTO.getTitle());

        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new RuntimeException("Banner不存在");
        }

        BeanUtils.copyProperties(updateDTO, banner);
        bannerMapper.updateById(banner);
        log.info("Banner更新成功，ID: {}", id);
    }

    @Override
    public void deleteBanner(Long id) {
        log.info("删除Banner: {}", id);

        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new RuntimeException("Banner不存在");
        }

        bannerMapper.deleteById(id);
        log.info("Banner删除成功，ID: {}", id);
    }

    @Override
    public void enableBanner(Long id) {
        log.info("启用Banner: {}", id);

        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new RuntimeException("Banner不存在");
        }

        banner.setStatus(1);
        bannerMapper.updateById(banner);
        log.info("Banner启用成功，ID: {}", id);
    }

    @Override
    public void disableBanner(Long id) {
        log.info("禁用Banner: {}", id);

        Banner banner = bannerMapper.selectById(id);
        if (banner == null) {
            throw new RuntimeException("Banner不存在");
        }

        banner.setStatus(0);
        bannerMapper.updateById(banner);
        log.info("Banner禁用成功，ID: {}", id);
    }

    @Override
    public String uploadBannerImage(MultipartFile file, HttpServletRequest request) {
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }

        try {
            log.info("开始上传Banner图片到Minio，原始文件名: {}", file.getOriginalFilename());

            // 生成唯一的对象名称
            String objectName = minioService.generateUniqueFileName(file.getOriginalFilename(), "banners");

            // 上传到Minio并记录到数据库
            String fileUrl = minioService.uploadFile(
                file, objectName, "banners", null, "banner", request);

            log.info("Banner图片上传成功到Minio，对象名称: {}, 访问URL: {}", objectName, fileUrl);
            return fileUrl;

        } catch (Exception e) {
            log.error("Banner图片上传到Minio失败", e);
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }

    @Override
    public void updateBannerSort(List<Long> bannerIds) {
        log.info("批量更新Banner排序: {}", bannerIds);

        if (bannerIds == null || bannerIds.isEmpty()) {
            return;
        }

        for (int i = 0; i < bannerIds.size(); i++) {
            Long bannerId = bannerIds.get(i);
            Banner banner = bannerMapper.selectById(bannerId);
            if (banner != null) {
                banner.setSortOrder(i);
                bannerMapper.updateById(banner);
            }
        }

        log.info("Banner排序更新成功");
    }

    /**
     * 转换为BannerListVO
     */
    private BannerListVO convertToListVO(Banner banner) {
        BannerListVO vo = new BannerListVO();
        vo.setId(banner.getId());
        vo.setTitle(banner.getTitle());
        vo.setImageUrl(banner.getImageUrl());
        vo.setLinkUrl(banner.getLinkUrl());
        vo.setLinkType(banner.getLinkType());
        vo.setLinkTypeName(getLinkTypeName(banner.getLinkType()));
        vo.setSortOrder(banner.getSortOrder());
        vo.setStatus(banner.getStatus());
        vo.setStatusName(getStatusName(banner.getStatus()));

        // 格式化时间
        if (banner.getStartTime() != null) {
            vo.setStartTime(banner.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        if (banner.getEndTime() != null) {
            vo.setEndTime(banner.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        if (banner.getCreateTime() != null) {
            vo.setCreateTime(banner.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }

        return vo;
    }

    /**
     * 转换为BannerVO
     */
    private BannerVO convertToDetailVO(Banner banner) {
        BannerVO vo = new BannerVO();
        BeanUtils.copyProperties(banner, vo);
        vo.setLinkTypeName(getLinkTypeName(banner.getLinkType()));
        vo.setStatusName(getStatusName(banner.getStatus()));
        return vo;
    }

    /**
     * 获取链接类型名称
     */
    private String getLinkTypeName(Integer linkType) {
        if (linkType == null) return "未知";
        switch (linkType) {
            case 0: return "无链接";
            case 1: return "内部页面";
            case 2: return "外部链接";
            default: return "未知";
        }
    }

    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 0: return "禁用";
            case 1: return "启用";
            default: return "未知";
        }
    }
}